//
///** @file third.h
//    This file shows how to configure a tenacitas::async::handlers.
//    There is only one type of event_t, and the handler creator the handler class  
//*/
//
///** @example third.h */
//
//#include <cstdint>
//#include <string>
//
//#include <boost/thread/thread.hpp>
//#include <boost/thread/mutex.hpp>
//
//#include <tenacitas_async/handlers.h>
//#include <tenacitas_async/event.h>
//
//
//
//
//using namespace std;
//using namespace tenacitas;
//
//namespace tenacitas {
//    namespace async {
//        /** namepsace created for the first test of tenacitas::async */
//        namespace test_3 {
//            
//            /** The type of event_t that will be handled */
//            typedef async::event2<0, uint16_t, string> event_2;
//
//            /** The handler class that will handle the event_t */
//            template <typename t_logger>
//            class handler {
//            public:
//                
//                /** The type of pointer of the handler */
//                typedef std::shared_ptr<handler> ptr_t;
//
//                /** Type for the logger used  */
//                typedef t_logger logger_t;                
//
//                /** Contructor */
//                handler( )
//                    : m_mutex( ) {}
//
//                static ptr_t instance( ) {
//                    if ( !m_instance ) {
//                        m_instance = ptr_t( new handler( ) );
//                    }
//                    return m_instance;
//                }
//
//                /** The operator that handles the event_t */
//                void operator( ) ( event_2::ptr_t p_event ) {
//
//                    boost::lock_guard<boost::mutex> l_lock(m_mutex);
//
//                    log_begin( logger_t );
//
//                    // taking it easy...
//                    boost::this_thread::sleep(boost::posix_time::seconds(4));
//                    
//                    log_info( logger_t ) << "\t\tevent "
//                                         << event_2::id << " output: "
//                                         << *p_event; 
//        
//                    log_end( logger_t );
//
//                }
//
//
//
//                /**  Method that will create the first 2 handler_ptr_t objects */
//                template<typename t_handlers>
//                void first_creation( event_id &&, t_handlers & p_handlers ) {
//
//                    for ( uint16_t l_counter = 0; l_counter < 2; ++l_counter ) {
//                        p_handlers.add( ptr_t( new handler ( ) ) );
//                    }
//                }
//
//                // Method that will create additional 1 handler::ptr_t object
//                template<typename t_handlers>
//                bool additional_creation( event_id &&, t_handlers & p_handlers ) {
//                    // p_handlers.add( handler_ptr_t( new handler_t( ) ) );
//                    // return true;
//                    return false;
//                }
//
//            private:
//                /** A handler is to be called in a multi-threaded envinronment */
//                boost::mutex m_mutex;
//
//                /** Single instance */
//                static ptr_t m_instance;
//            };
//
//            
//            template <typename t_logger>
//            typename handler<t_logger>::ptr_t
//            handler<t_logger>::m_instance;
//
//            ///** Groups the types necessary for a tenacitas::async::handlers
//            //    
//            //    @tparam t_logger is left as a template, so that the same logger
//            //    can be used by many tests
//            //*/
//            //template <typename t_logger>
//            //class supplier {
//            //public:
//            //    /** Type for the logger */
//            //    typedef t_logger logger_t;
//
//            //    /** Type for the event_t */
//            //    typedef event_2 event_t;
//
//            //    /** Type of the event_t handler */
//            //    typedef handler<logger_t> handler_t;
//
//            //    /** Type for the handler creator,
//            //        which is the the handler class */
//            //    typedef handler<logger_t> handler_factory_t;
//            //};
//            
//                
//            
//            /** Runs the test
//
//                @tparam t_logger is left as a template, so that the same logger
//                can be used by many tests
//            */
//            template <typename t_logger>
//            void run( ) {
//
//
//                /** Type for the logger */
//                typedef t_logger logger_t;
//
//                /** Type for the event_2 */
//                typedef typename event_2 event_t;
//
//                typedef typename event_2::ptr_t event_ptr_t;
//                
//                typedef handler<t_logger> handler_t;
//
//                typedef handler<t_logger> handler_factory_t;
//
//                typedef typename handler_factory_t::ptr_t handler_factory_ptr_t;
//
//                /** Type for the handlers class */
//                typedef handlers<
//                    logger_t, 
//                    event_t, 
//                    handler_t, 
//                    handler_factory_t 
//                > handlers_t;
//
//                // lets go!!
//                log_begin( logger_t );
//
//                // we'll fire 25 events
//
//                // remember that handler_factory will initialy create only 2
//                // handlers, and an extra one each time handlers cant find a free
//                // handler
//
//                // also keep in mind that each handler sleeps for 2 seconds
//                uint16_t l_num_events ( 20 );
//
//                // to format the string part of the event_t
//                stringstream l_stream;
//
//                // to count the events fired
//                uint16_t l_counter ( 0 );
//
//                handler_factory_ptr_t l_handler_factory( new handler_factory_t( ) );
//                handlers_t l_handlers( l_handler_factory );
//
//                while ( true ) {
//
//                    if ( l_counter == l_num_events ) {
//                        break;
//                    }
//                    
//                    // breathing...
//                    boost::this_thread::sleep(boost::posix_time::millisec(10));
//
//                    log_debug( logger_t ) << "event_t number " << l_counter;
//
//                    // formating the string part of the event_t
//                    l_stream.str( "" );
//                    l_stream << "counter " << l_counter;
//                    
//                    event_ptr_t l_event ( new event_t ( l_counter, l_stream.str( ) ) );
//
//                    // sending the event_t to be handled
//                    l_handlers.handle( l_event );
//
//                    ++l_counter;
//                }
//            }
//        }
//    }
//}
